--- 连利485光电直读水表协议
module(..., package.seeall)

local logtag = "LL485"
local cid, uid = 3, 3 -- 默认用3通道
local dtu, udtu = {}, {} -- 配置文件
local read_meter_adr = 'FEFE6819AAAAAAAAAAAAAA03030A8101B916'
local read_meter_dat = '337801031F9001'
local meter_adr = ''
local meter_val = nil
function setDtu(dtup, udtup)
    dtu, udtu = dtup, udtup
    -- 如果设置是本协议
    if udtu and tonumber(udtu.dtype) == 1 then sys.taskInit(init) end
end
local function process(data, status)
    if status == 0 and #data > 10 then -- 读取的地址
        meter_adr = data:sub(5, 9):toHex()
        lcd.LCD_DATA[3] = '水表地址:' .. (meter_adr or "NULL")
    elseif status == 1 and #data > 20 then
        meter_val = string.format("%02X%02X%02X", data:byte(20), data:byte(19), data:byte(18))
        usrdata.update(meter_val)
        lcd.LCD_DATA[3] = '水表读数:' .. (meter_val or 0)
    end
end
local function read_meter_val()
    local head = '6819' .. meter_adr .. read_meter_dat
    local sum = string.format("%02X", string.checkSum(head:fromHex(), 1))
    sys.publish("UART_SENT_RDY_" .. uid, uid, ('FEFE' .. head .. sum .. '16'):fromHex())
    --lcd.LCD_DATA[3] = string.format("U%dD%d READING",uid,udtu.dtype)
end

function init()
    power.openBoost()
    sys.wait(1000)
    -- 1、读取表地址
    -- 2、读取表值
    local status = nil
    -- 测试 表读数
    -- process(("FE FE 68 19 78 56 34 12 00 33 78 81 16 1F 90 01 00 56 34 12 2C 00 00 00 00 2C 00 00 00 00 00 00 00 00 00 7B 16"):fromHex(),1)
    while true do
        -- 读取表地址
        if not meter_adr or #meter_adr == 0 then
            sys.publish("UART_SENT_RDY_" .. uid, uid, read_meter_adr:fromHex())
            status = 0 -- 正在读取表地址
        else
            status = 1 -- 正在读表值
            read_meter_val()
        end
        log.warn(logtag, "间隔5秒等待串口数据,UART" .. uid)
        -- 等待串口回复
        result, data = sys.waitUntil('UART_READ_DONE_NEXT_' .. uid, 5000)
        if result then
            if (data) then
                -- log.warn(logtag, '收到串口' .. uid .. '回复数据:', data)
                process(data, status)
            end
            if status == 1 then sys.wait(2*1000) end
        else
            lcd.LCD_DATA[3] = "LL485 READ TIMEOUT"
        end
    end
end
